#!/bin/bash
###############################################################################
# This script is run for each candidate to evaluate it after all
# candidate configurations have been run on a single instance.
#
# Check the examples in examples/
#
# PARAMETERS:
# $1 is the candidate number
# $2 is the instance id
# $3 is the seed
# $4 is the instance name
# $5 is the number of candidates alive in this iteration
#
# ONLY FOR ELITIST RACE: The rest ($* after `shift 5') are the ids of the
# candidates alive in this iteration. This list can be used to calculate the
# hypervolume using only active candidates.
#
# RETURN VALUE:
# This script should print one numerical value: the cost that must be minimized.
# Exit with 0 if no error, with 1 in case of error
###############################################################################

error() {
    echo "`TZ=UTC date`: $0: error: $@"
    if [ -s error.log ]; then
        cat error.log
    fi
    exit 1
}

error_sleep() {
    echo "`TZ=UTC date`: $0: error: $@" >> error.log
    sleep 60
}

NORMALIZATION_RANGE="'1 2'"
REFERENCE_POINT="'2.1 2.1'"

# A program that normalizes all _dat files to [0, 1]
NORMALIZE="../nondominated --verbose -n $NORMALIZATION_RANGE -s '_nor'"
UPDATELIMITS="2>&1 | grep -E '# Total minimum|# Total maximum'  | sed  's/:/:\n/'"

# A program for computing the hypervolume. Download hypervolume
HV="../hv --quiet -r $REFERENCE_POINT"



CANDIDATE="$1"
INSTANCEID="$2"
SEED="$3"
INSTANCE="$4"
TOTALCANDIDATES="$5"
shift 5 || error "Not enough parameters"
ALLIDS=$*

STDOUT=c${CANDIDATE}-${INSTANCEID}-${SEED}.stdout
STDERR=c${CANDIDATE}-${INSTANCEID}-${SEED}.stderr

calc_measure() {
    LIMITSFILE=limits-${INSTANCEID}.txt
    LIMITSTMP=limits-${INSTANCEID}.tmp
    if [ -s "$LIMITSFILE" ]; then
        eval "$NORMALIZE $LIMITSFILE $ALLFILES $UPDATELIMITS" > $LIMITSTMP
        rm -f ${LIMITSFILE}
        mv $LIMITSTMP $LIMITSFILE
    else
       eval "$NORMALIZE $ALLFILES $UPDATELIMITS" > $LIMITSFILE
    fi
}

# TODO: Use /tmp for all temporary files, i.e., put target-data under /tmp
cd target-data || error "cannot change to directory 'target-data'"

ALLFILES=
for FILENAME in $ALLIDS; do
    ALLFILES="$ALLFILES c${FILENAME}-${INSTANCEID}-${SEED}.stdout"
done

# First normalize output files, unless they are ready.
while ! ls ${ALLFILES}_nor &> /dev/null ; do
    # Check that all output files are there
    NUM=$(ls -1 ${ALLFILES} 2> /dev/null | wc --lines)
    if [ "$NUM" -ne "$TOTALCANDIDATES" ]; then
        error_sleep "only found $NUM files out of $TOTALCANDIDATES: ${ALLFILES}"
        continue
    fi
    # Check every STDERR
    for FILENAME in $ALLFILES; do
        FILESTDERR=${FILENAME/stdout/stderr}
	[ OK = "$(cat ${FILESTDERR})" ] || continue
        [ -s "$FILENAME" ] || continue
    done
    calc_measure
    rm -f error.log
    # Comment out if you wish to keep all output files around
    comm --output-delimiter=" " -23 <(ls -1 c*-*.* | sort) <(ls -1 ${ALLFILES//-${INSTANCEID}-${SEED}.stdout/-*.*} | sort) | xargs -r rm -f
    break
done



if [ ! -s "${STDOUT}_nor" ]; then
    error "${STDOUT}_nor: No such file or directory"
fi
COST=$(eval "$HV ${STDOUT}_nor" || error "calculating hypervolume failed")
# Negative because hypervolume is maximised but irace minimises.
echo "-$COST"

exit 0


